home *** CD-ROM | disk | FTP | other *** search
- PROGRAM MineHelp;
- {Version 1.0
- Peter Karrer
- April 26, 1992}
-
- {$M 40960,8192}
- {$G+}
-
- USES WObjects, WinTypes, WinProcs, Strings;
-
- {$R MINEHELP.RES}
-
- CONST
- appName: PCHAR = 'MineHelp';
- {Child control IDs}
- inactive = 103;
- active = 104;
- automatic = 105;
- basic = 106;
- expert = 107;
- rand = 108;
- id_Animation = 110;
- id_OK = 109;
-
- white = $ffffff;
- {colors masked with $ffc0c0c0}
- blue = $c00000;
- dblue = $800000;
- red = $0000c0;
- dred = $000080;
- dgreen= $008000;
- dcyan = $808000;
- black = 0;
- dgray = $808080;
- gray = $c0c0c0;
- xOff = -4; { width of left border in Minesweeper window client area - 16}
- yOff = 39; { width of top border in Minesweeper window client area - 16}
-
- TYPE
-
- TThisApp = OBJECT(TApplication)
- PROCEDURE InitMainWindow; VIRTUAL;
- END;
-
- PThisWindow = ^TThisWindow;
- TThisWindow = OBJECT(TDlgWindow)
- stat: INTEGER; {id of checked "Status" button}
- lev: INTEGER; {id of checked "Level" button}
- animation: BOOLEAN;
- msWin: HWnd;
- mswX, mswY: INTEGER;
- dimX, dimY: INTEGER;
- busy: BOOLEAN;
- CONSTRUCTOR Init;
- FUNCTION GetClassName: PCHAR; VIRTUAL;
- PROCEDURE GetWindowClass(VAR c: TWndClass); VIRTUAL;
- PROCEDURE SetupWindow; VIRTUAL;
- PROCEDURE DefChildProc(VAR msg: TMessage); VIRTUAL;
- PROCEDURE WMDestroy(VAR msg: TMessage); VIRTUAL wm_first + wm_Destroy;
- PROCEDURE WMTimer(VAR msg: TMessage); VIRTUAL wm_first + wm_Timer;
- PROCEDURE DoIt;
- FUNCTION GetMsWin: HWnd;
- PROCEDURE GetBoard(VAR bomb: BOOLEAN);
- PROCEDURE Click(x, y: INTEGER; btnDown, btnUp, modifier: WORD);
- PROCEDURE Mark(x, y: INTEGER);
- PROCEDURE ClearFields(VAR somethingDone: BOOLEAN);
- PROCEDURE MarkFields(VAR somethingDone: BOOLEAN);
- FUNCTION TwoFieldSearch(x1, y1, x2, y2: INTEGER): BOOLEAN;
- PROCEDURE TwoFields(VAR success: BOOLEAN);
- PROCEDURE ClearRandom(VAR somethingHappened: BOOLEAN);
- END;
-
- VAR
- thisApp: TThisApp;
- bb: ARRAY [0..25, 0..31] OF INTEGER;
- ee: ARRAY [0..25, 0..31] OF INTEGER;
-
- CONSTRUCTOR TThisWindow.Init;
- BEGIN
- TDlgWindow.Init(NIL, appName);
- END;
-
- FUNCTION TThisWindow.GetClassName;
- BEGIN
- GetClassName := appName;
- END;
-
- PROCEDURE TThisWindow.GetWindowClass(VAR c: TWndClass);
- BEGIN
- TDlgWindow.GetWindowClass(c);
- {c.hIcon := LoadIcon(hInstance, appName); doesn't work?!}
- END;
-
- PROCEDURE TThisWindow.SetupWindow;
- VAR
- i: INTEGER;
- BEGIN
- TDlgWindow.SetupWindow;
- IF SetTimer(hWindow, 1, 1000, NIL) = 0 THEN BEGIN
- MessageBox(HWindow, 'Sorry, no timers', NIL, mb_Ok);
- Destroy;
- END;
- {Setting the icon didn't work in GetWindowClass, dunno why}
- SetClassWord(hWindow, GCW_HICON, LoadIcon(hInstance, appName));
- animation := POS('n', ParamStr(1)) <> 0;
- IF POS('h', ParamStr(1)) <> 0 THEN BEGIN
- cmdShow := sw_Hide;
- END ELSE IF POS('c', ParamStr(1)) <> 0 THEN BEGIN
- cmdShow := sw_Minimize;
- END;
- IF POS('a', ParamStr(1)) <> 0 THEN BEGIN
- stat := active;
- END ELSE IF POS('i', ParamStr(1)) <> 0 THEN BEGIN
- stat := inactive;
- END ELSE BEGIN
- stat := automatic;
- END;
- IF POS('b', ParamStr(1)) <> 0 THEN BEGIN
- lev := basic;
- END ELSE IF POS('r', ParamStr(1)) <> 0 THEN BEGIN
- lev := rand;
- END ELSE BEGIN
- lev := expert;
- END;
- SendDlgItemMsg(stat, bm_SetCheck, 1, 0);
- SendDlgItemMsg(lev, bm_SetCheck, 1, 0);
- SendDlgItemMsg(id_animation, bm_SetCheck, ORD(animation), 0);
- RANDOMIZE;
- busy := FALSE;
- END;
-
- PROCEDURE TThisWindow.Click(x, y: INTEGER; btnDown, btnUp, modifier: WORD);
- BEGIN
- IF animation THEN BEGIN
- SetCursorPos(mswX + xOff + 16*x + 8, mswY + yOff + 16*y + 8);
- END;
- SendMessage(msWin, btnDown, modifier, MakeLong(xOff + 16*x, yOff + 16*y));
- SendMessage(msWin, btnUp, modifier, MakeLong(xOff + 16*x, yOff + 16*y));
- END; {Click}
-
- PROCEDURE TThisWindow.GetBoard(VAR bomb: BOOLEAN);
- {Examine the Minesweeper window client area. Get the contents of the
- individual squares by reading pixels at strategic locations. Colors
- are masked with $FFC0C0C0, because not all display drivers use the same
- intensities for colors like dark cyan or dark red}
- VAR
- x, y, v: INTEGER;
- rgb: LONGINT;
- msDC: HDC;
- BEGIN
- bomb := FALSE;
- msDC := GetDC(msWin);
- FOR y := 1 TO dimY DO BEGIN
- FOR x := 1 TO dimX DO BEGIN
- rgb := GetPixel(msDC, xOff + 9 + 16*x, yOff + 12 + 16*y) AND $ffc0c0c0;
- IF rgb = blue THEN BEGIN
- bb[y, x] := 1;
- END ELSE IF rgb = dgreen THEN BEGIN
- bb[y, x] := 2;
- END ELSE IF rgb = red THEN BEGIN
- bb[y, x] := 3;
- END ELSE IF rgb = dblue THEN BEGIN
- bb[y, x] := 4;
- END ELSE IF rgb = dred THEN BEGIN
- bb[y, x] := 5;
- END ELSE IF rgb = dcyan THEN BEGIN
- bb[y, x] := 6;
- END ELSE IF rgb = black THEN BEGIN
- rgb := GetPixel(msDC, xOff + 7 + 16*x, yOff + 6 + 16*y);
- IF rgb = white THEN BEGIN
- bb[y, x] := -2; bomb := TRUE; {mine}
- END ELSE BEGIN
- rgb := rgb AND $ffc0c0c0;
- IF rgb = gray THEN BEGIN
- bb[y, x] := 7;
- END ELSE IF rgb = red THEN BEGIN
- bb[y, x] := 128; {flag}
- END ELSE IF rgb = black THEN BEGIN
- bb[y, x] := 2049; {question mark}
- END ELSE BEGIN
- bb[y, x] := -999; bomb := TRUE; {invisible}
- END;
- END;
- END ELSE IF rgb = dgray THEN BEGIN
- bb[y, x] := 8;
- END ELSE IF rgb = gray THEN BEGIN
- rgb := GetPixel(msDC, xOff + 15 + 16*x, yOff + 1 +16*y) AND $ffc0c0c0;
- IF rgb = gray THEN BEGIN
- bb[y, x] := 0;
- END ELSE IF rgb = dgray THEN BEGIN
- rgb := GetPixel(msDC, xOff + 5 + 16*x, yOff + 5 +16*y) AND $ffc0c0c0;
- IF rgb = black THEN BEGIN
- bb[y,x] := 2049; {question mark}
- END ELSE IF rgb = gray THEN BEGIN
- bb[y, x] := 2048; {covered}
- END ELSE BEGIN
- bb[y, x] := -999; bomb := TRUE;
- END;
- END ELSE BEGIN
- bb[y, x] := -999; bomb := TRUE; {invisible}
- END;
- END ELSE BEGIN
- bb[y, x] := -999; bomb := TRUE; {invisible}
- END;
- END; {FOR x}
- END; {FOR y}
- ReleaseDC(msWin, msDC);
- IF NOT bomb THEN BEGIN
- FOR y := 1 TO dimY DO BEGIN
- FOR x := 1 TO dimX DO BEGIN
- v := bb[y, x];
- IF (v > 0) AND (v <= 8) THEN BEGIN
- ee[y, x] := bb[y-1,x-1]+bb[y-1,x]+bb[y-1,x+1]+bb[y,x-1]+
- bb[y,x+1]+bb[y+1,x-1]+bb[y+1,x]+bb[y+1,x+1];
- END ELSE BEGIN
- ee[y, x] := 0;
- END;
- END; {FOR x}
- END; {FOR y}
- END; {NOT bomb}
- END; {GetBoard}
-
- FUNCTION TThisWindow.GetMsWin: HWnd;
- {Find the Minesweeper window and its location on the screen}
- VAR
- w, mW: HWnd;
- st: ARRAY[0..32] OF CHAR;
- rp: RECORD
- CASE INTEGER OF 1: (r: TRect);
- 2: (p: TPoint);
- END;
- i: INTEGER;
- BEGIN
- w := 0;
- mW := 0;
- w := GetWindow(hWindow, gw_HWndFirst);
- WHILE (w <> 0) AND (mW = 0) DO BEGIN
- GetWindowText(w, st, 32);
- IF StrComp(st, 'Minesweeper') = 0 THEN BEGIN
- mW := w;
- GetClientRect(mW, rp.r);
- dimX := (rp.r.right - 24) DIV 16;
- dimY := (rp.r.bottom - 67) DIV 16;
- ClientToScreen(mW, rp.p);
- mswX := rp.p.x;
- mswY := rp.p.y;
- END;
- w := GetNextWindow(w, gw_HWndNext);
- END;
- IF mW <> 0 THEN BEGIN
- FOR i := 0 TO dimX + 1 DO BEGIN
- bb[0, i] := 0;
- ee[0, i] := 0;
- bb[dimY + 1, i] := 0;
- ee[dimY + 1, i] := 0;
- END;
- FOR i:= 1 TO dimY DO BEGIN
- bb[i, 0] := 0;
- ee[i, 0] := 0;
- bb[i, dimX + 1] := 0;
- ee[i, dimX + 1] := 0;
- END;
- END;
- GetMsWin := mW;
- END; {GetMsWin}
-
- PROCEDURE TThisWindow.ClearFields(VAR somethingDone: BOOLEAN);
- VAR
- x, y, v, c: INTEGER;
- BEGIN
- somethingDone := FALSE;
- FOR y := 1 TO dimY DO BEGIN
- FOR x := 1 TO dimX DO BEGIN
- v := bb[y, x];
- IF (v > 0) AND (v <= 8) THEN BEGIN
- c := ee[y, x];
- IF c >= 2048 THEN BEGIN {at least 1 covered field}
- c := c AND 2047 SHR 7; {number of flagged fields}
- IF v = c THEN BEGIN
- Click(x, y, wm_LButtonDown, wm_LButtonUp, mk_RButton);
- somethingDone := TRUE;
- IF stat <> automatic THEN BEGIN
- EXIT;
- END;
- END;
- END;
- END; {IF (v > 0) ..}
- END; {FOR x}
- END; {FOR y}
- END; {ClearFields}
-
- PROCEDURE TThisWindow.Mark(x, y: INTEGER);
- BEGIN
- Click(x, y, wm_RButtonDown, wm_RButtonUp, 0);
- IF bb[y, x] = 2049 THEN BEGIN {question mark}
- Click(x, y, wm_RButtonDown, wm_RButtonUp, 0);
- END;
- bb[y, x] := 128; {make it flagged}
- END; {Mark}
-
- PROCEDURE TThisWindow.MarkFields(VAR somethingDone: BOOLEAN);
- VAR
- x, y, v, c, f: INTEGER;
- BEGIN
- somethingDone := FALSE;
- FOR y := 1 TO dimY DO BEGIN
- FOR x := 1 TO dimX DO BEGIN
- v := bb[y, x];
- IF (v > 0) AND (v <= 8) THEN BEGIN
- c := bb[y-1,x-1]+bb[y-1,x]+bb[y-1,x+1]+bb[y,x-1]+
- bb[y,x+1]+bb[y+1,x-1]+bb[y+1,x]+bb[y+1,x+1];
- f := c SHR 11; {number of covered fields}
- IF f <> 0 THEN BEGIN
- c := c AND 2047 SHR 7; {number of flagged fields}
- IF (f + c) = v THEN BEGIN
- IF bb[y-1,x-1] >= 2048 THEN BEGIN Mark(x-1,y-1); END;
- IF bb[y-1,x ] >= 2048 THEN BEGIN Mark(x, y-1); END;
- IF bb[y-1,x+1] >= 2048 THEN BEGIN Mark(x+1,y-1); END;
- IF bb[y ,x-1] >= 2048 THEN BEGIN Mark(x-1,y ); END;
- IF bb[y, x+1] >= 2048 THEN BEGIN Mark(x+1,y ); END;
- IF bb[y+1,x-1] >= 2048 THEN BEGIN Mark(x-1,y+1); END;
- IF bb[y+1,x ] >= 2048 THEN BEGIN Mark(x, y+1); END;
- IF bb[y+1,x+1] >= 2048 THEN BEGIN Mark(x+1,y+1); END;
- somethingDone := TRUE;
- IF stat <> automatic THEN BEGIN
- EXIT;
- END;
- END;
- END;
- END; {IF (v > 0) ..}
- END; {FOR x}
- END; {FOR y}
- END; {MarkFields}
-
- FUNCTION TThisWindow.TwoFieldSearch(x1, y1, x2, y2: INTEGER): BOOLEAN;
- VAR
- a, b, c, x, y, na, nb: INTEGER;
-
- PROCEDURE ClickFields(xx1, yy1, xx2, yy2: INTEGER; marks: BOOLEAN);
- {Click on covered fields in environment of (x1,y1) but not of (x2,y2)}
- VAR
- xx, yy, dbg: INTEGER;
- BEGIN
- FOR yy := yy1 - 1 TO yy1 + 1 DO BEGIN
- FOR xx := xx1 - 1 TO xx1 + 1 DO BEGIN
- IF ((ABS(yy-yy2) > 1) OR (ABS(xx-xx2) > 1)) AND (bb[yy,xx] >= 2048) THEN BEGIN
- IF marks THEN BEGIN
- Mark(xx, yy);
- END ELSE BEGIN
- Click(xx, yy, wm_LButtonDown, wm_LButtonUp, 0);
- bb[yy, xx] := 0; {meaning uncovered with unknown value}
- END;
- END;
- END; {FOR xx}
- END; {FOR yy}
- TwoFieldSearch := TRUE;
- END; {ClickFields}
-
- BEGIN {TwoFieldSearch}
- TwoFieldSearch := FALSE;
- c := ee[y1, x1];
- x := bb[y1, x1] - c AND 2047 SHR 7; {Number of unknown mines around A=(x1,y1)}
- a := c SHR 11; {Number of covered fields around A=(x1,y1)}
- c := ee[y2, x2];
- y := bb[y2, x2] - c AND 2047 SHR 7; {Number of unknown mines around B=(x2,y2)}
- b := c SHR 11; {Number of covered fields around B=(x2,y2)}
- c := 0;
- IF (ABS(y1+1-y2) <=1) AND (ABS(x1-x2) <= 1) AND (bb[y1+1,x1] >= 2048) THEN c := c + 1;
- IF (ABS(y1+1-y2) <=1) AND (ABS(x1+1-x2)<=1) AND (bb[y1+1,x1+1]>=2048) THEN c := c + 1;
- IF (ABS(y1+1-y2) <=1) AND (ABS(x1-1-x2)<=1) AND (bb[y1+1,x1-1]>=2048) THEN c := c + 1;
- IF (ABS(y1-y2) <= 1) AND (ABS(x1+1-x2)<= 1) AND (bb[y1,x1+1] >= 2048) THEN c := c + 1;
- IF (ABS(y1-y2) <= 1) AND (ABS(x1-1-x2)<= 1) AND (bb[y1,x1-1] >= 2048) THEN c := c + 1;
- IF (ABS(y1-1-y2) <=1) AND (ABS(x1-x2) <= 1) AND (bb[y1-1,x1] >= 2048) THEN c := c + 1;
- IF (ABS(y1-1-y2) <=1) AND (ABS(x1+1-x2)<=1) AND (bb[y1-1,x1+1]>=2048) THEN c := c + 1;
- IF (ABS(y1-1-y2) <=1) AND (ABS(x1-1-x2)<=1) AND (bb[y1-1,x1-1]>=2048) THEN c := c + 1;
- {c = number of covered fields common to the environments of A and B}
- a := a - c;
- b := b - c;
- na := -1;
- nb := -1;
- IF a = 0 THEN BEGIN
- na := 0;
- END ELSE IF x + b = y THEN BEGIN
- na := 0;
- END ELSE IF x - a = y THEN BEGIN
- na := a;
- END ELSE IF b = 0 THEN BEGIN
- na := x - y;
- END;
- IF na >= 0 THEN BEGIN
- nb := y - x + na;
- END ELSE IF b = 0 THEN BEGIN
- nb := 0;
- END ELSE IF y - b = x THEN BEGIN
- nb := b;
- END ELSE IF a = 0 THEN BEGIN
- nb := y - x;
- END;
- IF nb >= 0 THEN BEGIN
- na := x - y + nb;
- END;
- IF a <> 0 THEN BEGIN
- IF na = 0 THEN BEGIN
- {Clear all fields in env A but not env B}
- ClickFields(x1, y1, x2, y2, FALSE);
- END ELSE IF na = a THEN BEGIN
- {Mark all those fields}
- ClickFields(x1, y1, x2, y2, TRUE);
- END;
- END;
- IF b <> 0 THEN BEGIN
- IF (nb = 0) AND (b <> 0) THEN BEGIN
- {Clear all fields in env B but not env A}
- ClickFields(x2, y2, x1, y1, FALSE);
- END ELSE IF nb = b THEN BEGIN
- {Mark all those fields}
- ClickFields(x2, y2, x1, y1, TRUE);
- END;
- END;
- END; {TwoFieldSearch}
-
- PROCEDURE TThisWindow.TwoFields(VAR success: BOOLEAN);
-
- PROCEDURE S(x1, y1: INTEGER);
- VAR
- x, y, miny, maxy: INTEGER;
- BEGIN
- IF success AND (stat <> automatic) THEN BEGIN
- EXIT;
- END;
- IF y1 >= 0 THEN BEGIN
- miny := 1;
- maxy := dimY - y1;
- END ELSE BEGIN
- miny := 1 - y1;
- maxy := dimY;
- END;
- FOR y := miny TO maxy DO BEGIN
- FOR x := 1 TO dimX - x1 DO BEGIN
- IF (ee[y, x] >= 2048) AND (ee[y + y1, x + x1] >= 2048) THEN BEGIN
- success := success OR TwoFieldSearch(x, y, x + x1, y + y1);
- IF success AND (stat <> automatic) THEN BEGIN
- EXIT;
- END;
- END;
- END;
- END;
- END; {S}
-
- BEGIN {TwoFields}
- success := FALSE;
- S(1, 0); S(0, -1); S(1, 1); S(1, -1); S(2, -1); S(2, 1);
- S(1, -2); S(1, 2); S(2, 0); S(0, -2); S(2, -2); S(2, 2);
- END; {TwoFields}
-
- PROCEDURE TThisWindow.ClearRandom(VAR somethingHappened: BOOLEAN);
- VAR
- x, y, c, i: INTEGER;
- bomb: BOOLEAN;
- BEGIN
- GetBoard(bomb);
- somethingHappened := FALSE;
- IF NOT bomb THEN BEGIN
- c := 0;
- FOR y := 1 TO dimY DO BEGIN
- FOR x:= 1 TO dimX DO BEGIN
- IF bb[y, x] >= 2048 THEN BEGIN
- c := c + 1;
- END;
- END;
- END;
- IF c <> 0 THEN BEGIN
- i := RANDOM(c);
- c := 0;
- FOR y := 1 TO dimY DO BEGIN
- FOR x := 1 TO dimX DO BEGIN
- IF bb[y, x] >= 2048 THEN BEGIN
- IF c = i THEN BEGIN
- Click(x, y, wm_LButtonDown, wm_LButtonUp, 0);
- somethingHappened := TRUE;
- EXIT;
- END;
- c := c + 1;
- END;
- END; {FOR x}
- END; {FOR y}
- END; {c <> 0}
- END; {NOT bomb}
- END; {ClearRandom}
-
- PROCEDURE WaitIdle;
- {It's impolite to hog the CPU}
- VAR
- m: TMsg;
- BEGIN
- WHILE PeekMessage(m, 0, 0, 0, pm_Remove) DO BEGIN
- IF m.message = wm_Quit THEN BEGIN
- HALT(m.wParam);
- END;
- TranslateMessage(m);
- DispatchMessage(m);
- END;
- END;
-
- PROCEDURE TThisWindow.DefChildProc(VAR msg: TMessage);
- VAR
- i: INTEGER;
- BEGIN
- WITH msg DO BEGIN
- IF (lParamLo <> 0) AND (lParamHi <> 1) THEN BEGIN
- { not menu, not accelerator id }
- IF wParam = inactive THEN BEGIN
- stat := inactive;
- END ELSE IF wParam = active THEN BEGIN
- stat := active;
- END ELSE IF wParam = automatic THEN BEGIN
- stat := automatic;
- END ELSE IF wParam = basic THEN BEGIN
- lev := basic;
- END ELSE IF wParam = expert THEN BEGIN
- lev := expert;
- END ELSE IF wParam = rand THEN BEGIN
- lev := rand;
- END ELSE IF wParam = id_Animation THEN BEGIN
- animation := NOT animation;
- SendDlgItemMsg(id_Animation, bm_SetCheck, ORD(animation), 0);
- END ELSE IF wParam = id_OK THEN BEGIN
- IF stat = active THEN BEGIN
- DoIt;
- END;
- END;
- END; {IF (lParamLo ..}
- END; {WITH msg}
- TDlgWindow.DefChildProc(msg);
- END;
-
- PROCEDURE TThisWindow.DoIt;
- VAR
- bomb, somethingHappened, action: BOOLEAN;
- x, y: INTEGER;
- m: TMsg;
- BEGIN
- IF busy THEN BEGIN
- {avoid reentrancy}
- EXIT;
- END;
- busy := TRUE;
- msWin := GetMsWin;
- IF msWin <> 0 THEN BEGIN
- REPEAT
- REPEAT
- GetBoard(bomb);
- action := FALSE;
- somethingHappened := TRUE;
- WHILE NOT bomb AND somethingHappened DO BEGIN
- MarkFields(somethingHappened);
- IF somethingHappened AND (stat <> automatic) THEN BEGIN
- busy := FALSE;
- EXIT;
- END;
- WaitIdle;
- action := action OR somethingHappened;
- {GetBoard(msWin, bomb);}
- END;
- somethingHappened := TRUE;
- WHILE NOT bomb AND somethingHappened DO BEGIN
- ClearFields(somethingHappened);
- IF somethingHappened AND (stat <> automatic) THEN BEGIN
- busy := FALSE;
- EXIT;
- END;
- WaitIdle;
- action := action OR somethingHappened;
- GetBoard(bomb);
- END;
- {action = there were changes in mark and clear phases}
- UNTIL NOT action OR bomb;
- somethingHappened := lev > basic;
- WHILE NOT bomb AND somethingHappened DO BEGIN
- TwoFields(somethingHappened);
- IF somethingHappened AND (stat <> automatic) THEN BEGIN
- busy := FALSE;
- EXIT;
- END;
- WaitIdle;
- action := action OR somethingHappened;
- GetBoard(bomb);
- END;
- IF (lev = rand) AND NOT action THEN BEGIN
- ClearRandom(action);
- IF stat <> automatic THEN BEGIN
- busy := FALSE;
- EXIT;
- END;
- END;
- UNTIL NOT action OR bomb;
- END; {msWin <> 0}
- busy := FALSE;
- END; {DoIt}
-
- PROCEDURE TThisWindow.WMTimer(VAR msg: TMessage);
- BEGIN
- IF stat = automatic THEN BEGIN
- DoIt;
- END;
- END;
-
- PROCEDURE TThisWindow.WMDestroy(VAR msg: TMessage);
- BEGIN
- KillTimer(hWindow, 1);
- TDlgWindow.WMDestroy(msg);
- END;
-
- PROCEDURE TThisApp.InitMainWindow;
- begin
- mainWindow := NEW(PThisWindow, Init);
- end;
-
- BEGIN
- {$G-}
- IF (GetWinFlags AND (wf_CPU086 OR wf_CPU186)) <> 0 THEN BEGIN
- MessageBox(0, 'WinHelp needs a 286 or better', NIL, mb_OK);
- HALT(0);
- END;
- {$G+}
- thisApp.Init(appName);
- thisApp.Run;
- thisApp.Done;
- END.
-